package com.jz;

import com.google.common.util.concurrent.RateLimiter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.exception.ZuulException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.DEBUG_FILTER_ORDER;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;

/**
 * Created by Hasee on 2022-02-25.
 */
@Component
@Slf4j
public class PreFilter extends ZuulFilter{
    //过滤类型
    @Override
    public String filterType() {
        return PRE_TYPE;
    }

    //过滤等级
    @Override
    public int filterOrder() {
        return DEBUG_FILTER_ORDER;
    }

    //是否开启过滤器
    @Override
    public boolean shouldFilter() {
        return true;
    }
    private static RateLimiter rateLimiter = RateLimiter.create(1);

    //要执行的任务
    @Override
    public Object run() throws ZuulException {
        //限流操作
        //1.防止恶意攻击
//        频繁的访问，压力测试工具，
        //每台机器 300 次每秒钟
      /*  log.info("==========前置过滤器22222222222222222==========");
        System.out.println("==========前置过滤器222222222222222==========");
        //1.令牌桶算法防止恶意攻击
        if (!rateLimiter.tryAcquire()){
            throw new ZuulException("Dang qian ren shu guo duo ",500,"cuowu ");
        }*/
        //每隔ip去控制访问次数
//        1.用人家的防火墙
//        2.不停的去分析哪些ip每秒钟访问的多，把那些异常的ip找出来对他进行限制访问。
//        代码：java可以识别访问者的ip，识别每个ip每秒的访问次数，限制异常ip
        //鉴权-鉴定权限

        //腾讯的思路：我们和腾讯对接接口，怎样保证腾讯过来的我们接收，非腾讯过来的我们不接受。
        //第一约束好一个关键词 token（令牌）：（jiaze + 用户名+密码）加密处理后的字符串
//        腾讯每次请求除了发送请求内容，还会把这个字符串连带着发给我们
//        我们服务器，在接收数据之前，会先拿着大家约束好的（token +用户名+密码）进行加密，拿着加密后的结果
        //比对腾讯发过来的加密的结果，如果一致就认为确实是腾讯发过来的请求，我这边就进行处理。

//        加密算法是腾讯官方提供的


        // 前端过来的请求，我们接收，其他过来的我们不接受
//        前端服务在发送请求到后台服务的时候，一定会携带一个加密的字符串
        //后台拿到加密的字符串进行比对，如果一致就允许访问接口，不一致不允许访问接口。
        //获取浏览器请求资源
       /* ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        //获取get资源
        HttpServletRequest request = requestAttributes.getRequest();
        //请求类型
        String method = request.getMethod();
        String requestURI = request.getRequestURI();
        String token =  request.getParameter("token");
        log.info("请求类型:"+method);
        log.info("请求地址:"+requestURI);
        if (!token.equals("123")){
            throw new ZuulException("fei fa fang wen!",500,"fei fa fang wen!");
        }*/
        //统一日志记录，高级用法：可以把一些统一类型的日志存储起来，redis
        log.info("============zuul========9091=========");
        return null;
    }
}
